﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Ex03.GarageLogic
{
    public enum eVehicleType
    {
        Motorcycle,
        Car,
        CommercialVehicle
    }

    public enum eEnergyType
    {
        Fuel,
        Electricity
    }

    /// <summary>
    /// responcible to create every type of vehicle
    /// this class is the only one who knows exactly which typs of vehicels the program seports
    /// </summary>
    internal static class VehicleGenerator
    {
        internal static Vehicle GenerateVehicle(eVehicleType i_VehicleType, eEnergyType i_EnergyType, string i_VehicleModelName, string i_VehicleLicenseNumber, string i_WheelsManufacturerName)
        {
            const int k_numOfWheelsInMotorcycle = 2;
            const int k_numOfWheelsInCar = 4;
            const int k_numOfWheelsInCommecialVehicle = 6;
            const float k_MotorcycleMaxAirPressure = 32;
            const float k_CarMaxAirPressure = 29;
            const float k_CommecialVehicleMaxAirPressure = 28;
            Vehicle newVehicle = null;

            if (i_VehicleType == eVehicleType.Motorcycle)
            {
                Wheel[] motorcycleWheels = createWhells(i_WheelsManufacturerName, k_numOfWheelsInMotorcycle, k_MotorcycleMaxAirPressure);
                newVehicle = createMotorcycle(i_EnergyType, i_VehicleModelName, i_VehicleLicenseNumber, motorcycleWheels);
            }
            else if (i_VehicleType == eVehicleType.Car)
            {
                Wheel[] carWheels = createWhells(i_WheelsManufacturerName, k_numOfWheelsInCar, k_CarMaxAirPressure);
                newVehicle = createCar(i_EnergyType, i_VehicleModelName, i_VehicleLicenseNumber, carWheels);
            }
            else if (i_VehicleType == eVehicleType.CommercialVehicle)
            {
                Wheel[] commercialVehicleWheels = createWhells(i_WheelsManufacturerName, k_numOfWheelsInCommecialVehicle, k_CommecialVehicleMaxAirPressure);
                newVehicle = createCommercialVehicle(i_EnergyType, i_VehicleModelName, i_VehicleLicenseNumber, commercialVehicleWheels);
            }
                        
            return newVehicle;
        }

        private static Vehicle createCommercialVehicle(eEnergyType i_EnergyType, string i_VehicleModelName, string i_VehicleLicenseNumber, Wheel[] i_CommercialVehicleWheels)
        {
            const eFuelType k_CommecialVehicleFuelType = eFuelType.Soler;
            const float k_CommercialVehicleFuelTankSize = 100;
            EnergySource newEnergySource;

            if (i_EnergyType == eEnergyType.Fuel)
            {
                newEnergySource = new FuelPowered(k_CommercialVehicleFuelTankSize, k_CommecialVehicleFuelType);
            }
            else
            {
                throw new ArgumentException("Commercial Vehicle cannot run on Electricity");
            }

            return new CommercialVehicle(i_VehicleModelName, i_VehicleLicenseNumber, i_CommercialVehicleWheels, newEnergySource);
        }

        private static Vehicle createCar(eEnergyType i_EnergyType, string i_VehicleModelName, string i_VehicleLicenseNumber, Wheel[] i_CarWheels)
        {
            const eFuelType k_CarFuelType = eFuelType.Octan95;
            const float k_CarFuelTankSize = 42;
            const float k_CarMaxBatteryCapacity = 2.8f;
            EnergySource newEnergySource;

            if (i_EnergyType == eEnergyType.Fuel)
            {
                newEnergySource = new FuelPowered(k_CarFuelTankSize, k_CarFuelType);
            }
            else
            {
                newEnergySource = new ElectricityPowered(k_CarMaxBatteryCapacity);
            }

            return new Car(i_VehicleModelName, i_VehicleLicenseNumber, i_CarWheels, newEnergySource);
        }

        private static Vehicle createMotorcycle(eEnergyType i_EnergyType, string i_VehicleModelName, string i_VehicleLicenseNumber, Wheel[] i_MotorcycleWheels)
        {
            const eFuelType k_MotorcycleFuelType = eFuelType.Octan96;
            const float k_MotorcyclFuelTankSize = 6;
            const float k_MotorcycleMaxBatteryCapacity = 2.4f;
            EnergySource newEnergySource;

            if (i_EnergyType == eEnergyType.Fuel)
            {
                newEnergySource = new FuelPowered(k_MotorcyclFuelTankSize, k_MotorcycleFuelType);
            }
            else
            {
                newEnergySource = new ElectricityPowered(k_MotorcycleMaxBatteryCapacity);
            }
            
            return new Motorcycle(i_VehicleModelName, i_VehicleLicenseNumber, i_MotorcycleWheels, newEnergySource);
        }

        private static Wheel[] createWhells(string i_WheelsManufacturerName, int i_numOfWheelsInMotorcycle, float i_MotorcycleMaxAirPressure)
        {
            Wheel[] wheels = new Wheel[i_numOfWheelsInMotorcycle];

            for (int i = 0; i < i_numOfWheelsInMotorcycle; i++)
            {
                wheels[i] = new Wheel(i_WheelsManufacturerName, i_MotorcycleMaxAirPressure);
            }

            return wheels;
        }
    }
}